package com.org.api.admin.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.org.api.admin.entity.po.*;
import com.org.api.admin.service.CmsUserBaseService;
import com.org.api.admin.service.CmsUserRedisService;
import com.org.api.admin.service.impl.CmsUserRedisServiceImpl;
import com.org.platform.model.ResultModel;
import com.org.platform.support.conponents.SpringApplicationContextAware;
import com.org.platform.utils.CommonUtil;
import com.org.platform.utils.LocalDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Description
 * @auther dh
 * @date 2022/2/21 12:35
 */
@Slf4j
@RestController
@RequestMapping(value = "/api/admin/test/redis")
public class CmsUserRedisController {

    private long indexId = 1491262145134997506L;
    public static final String startTimeString = "2022-02-28 18:32:54";
    public static final String endTimeString = "2022-03-12 17:01:04";
    public static final int isLongTeam = 0;
    public static final String[] currentAreaCodes = {"430050", "-1"};
    public static final String[] currentUserTypes = {"1103", "-1"};

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CmsUserRedisService cmsUserRedisService;

    /**
     * 保存首页区域数据
     *
     * @return
     */
    @RequestMapping(value = {"/indexSave"}, method = RequestMethod.GET)
    public ResultModel indexSave() {
//	以下以首页:平台:PC端:B2B数据为例
//	初始化首页数据
        CmsUserRedisIndex cmsUserRedisIndex = new CmsUserRedisIndex();
        cmsUserRedisIndex.setIndexId(indexId);
        cmsUserRedisIndex.setIsLongTeam(isLongTeam);
        cmsUserRedisIndex.setShowStartTime(startTimeString);
        cmsUserRedisIndex.setShowEndTime(endTimeString);
        cmsUserRedisIndex.setConfigStatus(1);
        cmsUserRedisIndex.setIsDelete(0);
        cmsUserRedisIndex.setIsDefault(0); // 默认首页
//  获取过期时间
        long expireTime = cmsUserRedisService.getModuleExpireTime(cmsUserRedisIndex);
//	初始化模块数据
        List<CmsUserRedisIndexModule> cmsIndexModuleList = new ArrayList<>();
        cmsIndexModuleList.add(new CmsUserRedisIndexModule(1L, 1, 0, expireTime,CmsUserModuleEnum.Navigation));
        cmsIndexModuleList.add(new CmsUserRedisIndexModule(2L, 2, 0, expireTime,CmsUserModuleEnum.Banner));
        cmsIndexModuleList.add(new CmsUserRedisIndexModule(3L, 3, 0, expireTime,CmsUserModuleEnum.GraphicNavigation));

//  首页为空则直接返回
        if (null == cmsUserRedisIndex) {
            return ResultModel.newFail();
        }

//	第2步:保存首页模块数据
        cmsUserRedisService.saveIndexModuleData(CmsUserRedisServiceImpl.modulePrefix, cmsIndexModuleList, cmsUserRedisIndex);

//  第3步:保存首页数据
        if (cmsUserRedisIndex.getIsDefault().equals(1)) {
//	  第3.1步: 默认首页 默认首页处理
            String defaultPrefix = "cms:ind:1:default:p:pc:b2b:";
            String[] defaultConfig = new String[]{"-1"};
            cmsUserRedisService.saveIndexData(defaultPrefix, defaultConfig, cmsUserRedisIndex);
        } else {
//		第3.2步：保存首页区域数据, 不限制区域:userAreas = new String[]{"-1"};
            String areaPrefix = "cms:ind:0:area:p:pc:b2b:";
            String[] userAreas = {"430050:0", "420100:1"}; // 这里面 1表示正常的Key,0表示删除的KEY,0的数据要放在前面
            cmsUserRedisService.saveIndexData(areaPrefix, userAreas, cmsUserRedisIndex);
//	  第3.3步: 保存首页标签数据,
            String tagPrefix = "cms:ind:0:tag:p:pc:b2b:";
            String[] userTag = {"1103:0", "1102:1"}; // 这里面 1表示正常的Key,0表示删除的KEY,0的数据要放在前面
            cmsUserRedisService.saveIndexData(tagPrefix, userTag, cmsUserRedisIndex);
        }
        return ResultModel.newSuccess();
    }

    @RequestMapping(value = {"/indexQuery"}, method = RequestMethod.GET)
    public ResultModel indexQuery() {

        long t1 = System.currentTimeMillis();

        String areaPrefix = "cms:ind:0:area:p:pc:b2b:"; // 表示 ind:首页,0:非默认,area:区域,p:平台

        String tagPrefix = "cms:ind:0:tag:p:pc:b2b:";

        Date now = new Date();
        long nowTimestamp = now.getTime();
        Double redisScore = Double.valueOf(nowTimestamp);
        Double redisMaxScore = Double.valueOf(CmsUserRedisServiceImpl.maxEndTimestamp);


//		  第1步： 判断是哪个首页
//      1.1: 先查询区域
		    Set<CmsUserRedisIndex> userAreaSet = new HashSet<>();
		    String[] userAreas = {"420100", "-1"};
		    for (String userArea : userAreas) {
		    	String areaKey = areaPrefix + userArea;
		    	Set<CmsUserRedisIndex> cmsAreaRedisIndexSet = redisTemplate.opsForZSet().rangeByScore(areaKey, redisScore, redisMaxScore);
		    	userAreaSet.addAll(cmsAreaRedisIndexSet);
		    }

//      1.2: 查标签
	      Set<CmsUserRedisIndex> userTagSet = new HashSet<>();
		    String[] userTags = {"1102", "-1"};
		    for (String userTag : userTags) {
			    String userTagKey = tagPrefix + userTag;
			    Set<CmsUserRedisIndex> cmsTagRedisIndexSet = redisTemplate.opsForZSet().rangeByScore(userTagKey, redisScore, redisMaxScore);
			    userTagSet.addAll(cmsTagRedisIndexSet);
		    }

        Set<CmsUserRedisIndex> resultRedisIndexSet = new HashSet<>();
        boolean userDefaultIndex = false;
        if (userAreaSet.size() <= 0 || userTagSet.size() <= 0) {
            userDefaultIndex = true;
        } else {
            //			这里取交集
            Set<CmsUserRedisIndex> userResultSet = new HashSet();
            userResultSet.addAll(userAreaSet);
            userResultSet.retainAll(userTagSet);
            if (userResultSet.size() <= 0) {
                userDefaultIndex = true;
            } else {
                Iterator<CmsUserRedisIndex> userResultIterator = userResultSet.iterator();
                while (userResultIterator.hasNext()) {
                    Object object = userResultIterator.next();
                    CmsUserRedisIndex cmsUserRedisIndex = CmsUserRedisServiceImpl.getObjectMapper().convertValue(object, CmsUserRedisIndex.class);
                    if (null == cmsUserRedisIndex || cmsUserRedisService.isLongTeamOrDefault(cmsUserRedisIndex)) {
                        continue;
                    }
                    String showStartTime = cmsUserRedisIndex.getShowStartTime();
                    String showEndTime = cmsUserRedisIndex.getShowEndTime();
                    LocalDateTime startTime = LocalDateUtil.localDateTimeParse(showStartTime, LocalDateUtil.FORMAT_PATTERN1);
                    LocalDateTime endTime = LocalDateUtil.localDateTimeParse(showEndTime, LocalDateUtil.FORMAT_PATTERN1);
                    if (startTime.compareTo(LocalDateTime.now()) > 0) {
                        userResultIterator.remove(); // 未开始
                    }
                    if (endTime.compareTo(LocalDateTime.now()) <= 0) {
                        userResultIterator.remove(); // 已结束
                    }
                }
                resultRedisIndexSet = userResultSet;
            }
        }
        if (userDefaultIndex) {
//    1.2	查不到则查默认
            String defaultPrefix = "cms:ind:1:default:p:pc:b2b:";
            String defaultUserKey = "-1";
            String defualtKey = defaultPrefix + defaultUserKey;
            resultRedisIndexSet = redisTemplate.opsForZSet().rangeByScore(defualtKey, redisScore, redisMaxScore);
            System.out.println(resultRedisIndexSet);
        }
        if (null == resultRedisIndexSet || resultRedisIndexSet.size() <= 0) {
            return ResultModel.newSuccess("获取首页失败");
        }
        Iterator cmsRedisIndexIterator = resultRedisIndexSet.iterator();
        Object obj = cmsRedisIndexIterator.next();
        CmsUserRedisIndex cmsUserRedisIndex = CmsUserRedisServiceImpl.getObjectMapper().convertValue(obj, CmsUserRedisIndex.class);
        log.info("cmsRedisIndex:{}", JSON.toJSONString(cmsUserRedisIndex));
//	第二步: 查询首页对应模块信息
        String moduleId = CmsUserRedisServiceImpl.modulePrefix + cmsUserRedisIndex.getIndexId();
        List<Object> moduleList = redisTemplate.opsForList().range(moduleId, 0, -1);
        log.info("moduleList:{}", JSON.toJSONString(moduleList));
//	第三步：通过模块id查询响应的详情数据
        List<Object> resultList = null;
        resultList = cmsUserRedisService.getIndexModuleData(moduleList);
        long t2 = System.currentTimeMillis();
        log.info("加载首页数据花费时长:{}", (t2 - t1));
        return ResultModel.newSuccess(resultList);
    }

    /**
     * 保存首页标签数据
     *
     * @return
     */
    @RequestMapping(value = {"/indexTagSave"}, method = RequestMethod.GET)
    public ResultModel indexTagSave() {
        String startTimeString = "2022-02-17 18:32:54";
        String endTimeString = "2022-02-28 18:32:54";
        Integer isLongTeam = 0;
        //	用户标签保存 (非默认首页，平台，pc端，b2b)
        String tagPrefix = "cms:ind:0:tag:p:pc:b2b:";
        String userTag = "1102";
        // 如果不限制标签则标签ID为 -1, userTag = "-1";
        LocalDateTime endDateTime = LocalDateUtil.localDateTimeParse(endTimeString, LocalDateUtil.FORMAT_PATTERN1);
        Date endDate = LocalDateUtil.localDateTimeToDate(endDateTime);
        long endTimestamp = endDate.getTime();
        if (isLongTeam.equals(1)) {
            endTimestamp = CmsUserRedisServiceImpl.maxEndTimestamp;
        }
        String userTagKey = tagPrefix + userTag;
        Date now = new Date();
        long nowTimestamp = now.getTime();
        String score = endTimestamp + "" + nowTimestamp;
        Double tagScore = Double.valueOf(score);
        CmsUserRedisIndex cmsUserRedisIndex = new CmsUserRedisIndex();
        cmsUserRedisIndex.setIndexId(indexId);
        cmsUserRedisIndex.setIsLongTeam(isLongTeam);
        cmsUserRedisIndex.setShowStartTime(startTimeString);
        cmsUserRedisIndex.setShowEndTime(endTimeString);
        redisTemplate.opsForZSet().add(userTagKey, cmsUserRedisIndex, tagScore);
        return ResultModel.newSuccess();
    }

    /**
     * 保存首页模块数据
     *
     * @return
     */
    @RequestMapping(value = {"/indexModuleSave"}, method = RequestMethod.GET)
    public ResultModel indexModuleSave() {
        // 首页设置结束时间
        String endTimeString = "2022-02-21 16:01:04";
        LocalDateTime endTime = LocalDateUtil.localDateTimeParse(endTimeString, LocalDateUtil.FORMAT_PATTERN1);
        if (endTime.compareTo(LocalDateTime.now()) < 0) {
            return ResultModel.newFail("首页已过期");
        }
        String moduleKeyPrefix = "cms:ind_mod:";
        String moduleKey = moduleKeyPrefix + indexId;
        // 第一步：删除Key
        redisTemplate.delete(moduleKey);

        // 第二步: 写值
        CmsUserRedisIndexModule cmsUserRedisIndexModule = new CmsUserRedisIndexModule(123456L,  1, 0, -1,CmsUserModuleEnum.Navigation);
        redisTemplate.opsForList().leftPush(moduleKey, cmsUserRedisIndexModule);
        cmsUserRedisIndexModule = new CmsUserRedisIndexModule(212341L, 2, 0, -1,CmsUserModuleEnum.Banner);
        redisTemplate.opsForList().leftPush(moduleKey, cmsUserRedisIndexModule);

        // 第三步: 设置过期时间
        if (!CommonUtil.isNullOrEmpty(endTimeString)) { // 如股首页长期有效则不设置过期时间
            LocalDateTime endDateTime = LocalDateUtil.localDateTimeParse(endTimeString, LocalDateUtil.FORMAT_PATTERN1);
            if (endDateTime.compareTo(LocalDateTime.now()) > 0) {
                Long sececonds = Duration.between(endDateTime, LocalDateTime.now()).getSeconds();
                redisTemplate.expire(moduleKey, sececonds + 10, TimeUnit.SECONDS);
            }
        }
        // 查询首页有哪些模块
        List<Map<String, Object>> list = redisTemplate.opsForList().range(moduleKey, 0, -1);
        List<CmsUserRedisIndexModule> cmsUserRedisIndexModuleList = JSONObject.parseArray(JSONObject.toJSONString(list), CmsUserRedisIndexModule.class);
        return ResultModel.newSuccess(cmsUserRedisIndexModuleList);
    }


    /**
     * 首页模块对应详情信息查询
     *
     * @return
     */
    @RequestMapping(value = {"/indexModuleDetailSave"}, method = RequestMethod.GET)
    public ResultModel indexModuleDetailSave() {
        // 首页设置结束时间
        String endTimeString = "2022-02-21 19:01:04";
        LocalDateTime endTime = LocalDateUtil.localDateTimeParse(endTimeString, LocalDateUtil.FORMAT_PATTERN1);
        if (endTime.compareTo(LocalDateTime.now()) < 0) {
            return ResultModel.newFail("首页已过期");
        }
        Long moduleConfigId = 212341L;
        String moduleKeyPrefix = "cms:ind_mod_detail:";

        Integer moduleType = 1;
        if (moduleType.equals(1)) {
            // 第一步：删除Key
            String moduleDetailKey = moduleKeyPrefix + moduleType + moduleConfigId;
            redisTemplate.delete(moduleDetailKey);
            CmsUserRedisIndexNavigation cmsUserRedisIndexNavigation = new CmsUserRedisIndexNavigation();
            cmsUserRedisIndexNavigation.setNavigationConfigId(1L);
            cmsUserRedisIndexNavigation.setAreaCodes("420100-2,430050-3");
            cmsUserRedisIndexNavigation.setTagCodes("1102");
            cmsUserRedisIndexNavigation.setTitle("测试数据");
            cmsUserRedisIndexNavigation.setPictureUrl("www.yyjzt.com");
            cmsUserRedisIndexNavigation.setLinkType(1);
            cmsUserRedisIndexNavigation.setLinkUrl("hao123.com");
            cmsUserRedisIndexNavigation.setLabelType(1);
            cmsUserRedisIndexNavigation.setSort(1);
            cmsUserRedisIndexNavigation.setIsLongTerm(0);
            cmsUserRedisIndexNavigation.setShowStartTime("2022-02-17 18:32:54");
            cmsUserRedisIndexNavigation.setShowEndTime("2022-02-19 18:32:54");
            redisTemplate.opsForList().leftPush(moduleDetailKey, cmsUserRedisIndexNavigation);
            // 第三步: 设置过期时间
            if (!CommonUtil.isNullOrEmpty(endTimeString)) { // 如股首页长期有效则不设置过期时间
                LocalDateTime endDateTime = LocalDateUtil.localDateTimeParse(endTimeString, LocalDateUtil.FORMAT_PATTERN1);
                if (endDateTime.compareTo(LocalDateTime.now()) > 0) {
                    Long sececonds = Duration.between(LocalDateTime.now(), endDateTime).getSeconds();
                    redisTemplate.expire(moduleDetailKey, sececonds + 10, TimeUnit.SECONDS);
                }
            }
        }

        return ResultModel.newSuccess();
    }


    @RequestMapping(value = {"/indexAreaQuery"}, method = RequestMethod.GET)
    public ResultModel indexAreaQuery() {
        //	用户区域查询数据
        String areaPrefix = "cms:ind:0:area:p:pc:b2b:";
        String queryEndTimeString = "2022-02-20 18:32:54";
        LocalDateTime queryEndDateTime = LocalDateUtil.localDateTimeParse(queryEndTimeString, LocalDateUtil.FORMAT_PATTERN1);
        Date queryEndDate = LocalDateUtil.localDateTimeToDate(queryEndDateTime);
        long queryEndTimestamp = queryEndDate.getTime();
        Date now = new Date();
        long nowTimestamp = now.getTime();
        String score = queryEndTimestamp + "" + nowTimestamp;
        String maxScore = CmsUserRedisServiceImpl.maxEndTimestamp + "" + nowTimestamp;
        Double userAreaScore = Double.valueOf(score);
        Double maxUserAreaScore = Double.valueOf(maxScore);
        String userAreaCode = "430050-3";
        String userAreaKey = areaPrefix + userAreaCode;
        Set<CmsUserRedisIndex> cmsUserRedisIndexSet = redisTemplate.opsForZSet().rangeByScore(userAreaKey, userAreaScore, maxUserAreaScore);
        return ResultModel.newSuccess(cmsUserRedisIndexSet);
    }

    @RequestMapping(value = {"/indexTagQuery"}, method = RequestMethod.GET)
    public ResultModel indexTagQuery() {
        //	用户区域查询数据
        String tagPrefix = "cms:ind:0:tag:p:pc:b2b:";
        String queryEndTimeString = "2022-02-28 18:32:59";
        LocalDateTime queryEndDateTime = LocalDateUtil.localDateTimeParse(queryEndTimeString, LocalDateUtil.FORMAT_PATTERN1);
        Date queryEndDate = LocalDateUtil.localDateTimeToDate(queryEndDateTime);
        long queryEndTimestamp = queryEndDate.getTime();
        Date now = new Date();
        long nowTimestamp = now.getTime();
        String score = queryEndTimestamp + "" + nowTimestamp;
        String maxScore = CmsUserRedisServiceImpl.maxEndTimestamp + "" + nowTimestamp;
        Double userTagScore = Double.valueOf(score);
        Double maxUserTagScore = Double.valueOf(maxScore);
        String userTagCode = "1102";
        String userTagKey = tagPrefix + userTagCode;
        Set<CmsUserRedisIndex> cmsUserRedisIndexSet = redisTemplate.opsForZSet().rangeByScore(userTagKey, userTagScore, maxUserTagScore);
        return ResultModel.newSuccess(cmsUserRedisIndexSet);
    }
}
